﻿
#include "RibbonStyle.hpp"
#include "RibbonCategory.hpp"
#include "RibbonPannel.hpp"

#include "RibbonAfrolAction.hpp"

#include "../OLApp/defines.hpp"
#include "RibbonMenu.hpp"
#include "RibbonAction.hpp"
#include "RibbonTitle.hpp"

#include <QSettings>

namespace NSRibbon {


	RibbonStyle::RibbonStyle(QMainWindow* p) : 
		QObject(),
		NSCore::AbstractObject(),
		m_p(p)
	{
		m_ribbon_title = new RibbonTitle(p);
		m_ribbon_dock = new QDockWidget(p);
		m_ribbon_dock->setFixedHeight(_S(125) + _S(32));
		m_ribbon_dock->setTitleBarWidget(new QWidget(p));
		m_ribbon_tab = new QTabWidget(p);
		QWidget* _dock_content = new QWidget(p);
		QVBoxLayout* _layout = new QVBoxLayout;

		_layout->setSpacing(0);
		_layout->setContentsMargins(0, 0, 0, 0);
		_dock_content->setLayout(_layout);
		m_ribbon_dock->setWidget(_dock_content);
		_layout->addWidget(m_ribbon_title);
		_layout->addWidget(m_ribbon_tab);

		m_p->addDockWidget(Qt::TopDockWidgetArea, m_ribbon_dock);

		m_ribbon_dock->setStyleSheet(QString("QTabBar::tab{min-height:%1px; }").arg(_S(30)));

		auto menu_btn= new QPushButton(m_p);
		menu_btn->setText("文件");
		m_main_menu = new QMenu(m_p);
		menu_btn->setMenu(m_main_menu);
		menu_btn->setFixedWidth(_S(55));
		menu_btn->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Minimum);
		menu_btn->setStyleSheet(R"(
			QPushButton {
				border:hidden; 
				padding: 10px 15px;
				background-color:#1E90FF; 
				color:#FFFFFF;
			}
			QPushButton:hover {
				background-color:#0080FF; 
			}
			QPushButton::menu-indicator {
			width:0px;
			})");
		m_ribbon_tab->setCornerWidget(menu_btn, Qt::BottomLeftCorner);
		//新建模型
		action_model_new = new QAction(QIcon(":/Res/icon_model_new.png"), tr("新建模型"), this);
		action_model_new->setShortcut(QKeySequence(Qt::CTRL+Qt::Key_N));
		//设置工作路径
		action_workpath = new QAction(QIcon(":/Res/icon_app_workpath.png"), tr("设置工作路径"), this);
		//打开文件
		m_menu_open = new QMenu("打开文件", m_p);
		m_menu_open->setIcon(QIcon(":/Res/icon_menu_open.png"));
		action_file_open = new QAction(QIcon(":/Res/icon_file_open.png"), tr("导入几何模型"), this);
		action_file_open->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_O));
		//导入几何点
		action_geompoint_open = new QAction(QIcon(":/Res/icon_points_open.png"), tr("导入几何点"), this);
		action_geompoint_open->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_G));
		m_menu_open->addAction(action_file_open);
		m_menu_open->addAction(action_geompoint_open);

		//最近打开
		m_recent_open = new QMenu(tr("最近打开"), m_p);
		//我的工具
		m_mytools = new QMenu(tr("我的工具箱"), m_p);
		m_mytools->setIcon(QIcon(":/Res/icon_app_mytools.png"));
		QAction* extract_rp_sw =new QAction(QIcon(":/Res/icon_app_solidworks.png"), tr("[工具文档]提取SolidWorks参考点"), this);
		m_mytools->addAction(extract_rp_sw);
		connect(m_mytools, &QMenu::triggered, this, &RibbonStyle::actionMyTools);

		//退出软件
		action_app_close = new QAction(QIcon(":/Res/icon_app_exit.png"), tr("退出"), this);
		action_app_close->setShortcut(QKeySequence(Qt::Key_Escape));
		//软件帮助
		action_app_help = new QAction(QIcon(":/Res/icon_app_help.png"), tr("帮助"), this);
		action_app_help->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_H));
		//内部信号槽连接
		connect(action_app_close, SIGNAL(triggered(bool /*checked*/)), this, SIGNAL(actionAppClose(bool/*checked*/)));
		connect(action_app_help, SIGNAL(triggered(bool /*checked*/)), this, SIGNAL(actionAppHelp(bool/*checked*/)));

		m_main_menu->addAction(action_model_new);
		m_main_menu->addSeparator();
		//m_main_menu->addAction(action_file_open);
		//m_main_menu->addAction(action_geompoint_open); 
		m_main_menu->addMenu(m_menu_open);
		m_main_menu->addMenu(m_recent_open);
		m_main_menu->addSeparator();
		m_main_menu->addAction(action_workpath);
		m_main_menu->addMenu(m_mytools);
		m_main_menu->addSeparator(); 
		m_main_menu->addAction(action_app_help);
		m_main_menu->addAction(action_app_close);

		connect(action_model_new, SIGNAL(triggered()), this, SLOT(actionModelNewSlot()));
		connect(action_workpath, SIGNAL(triggered()), this, SLOT(actionSetWorkpathSlot()));
		connect(action_file_open, SIGNAL(triggered()), this, SLOT(actionFileOpenSlot()));
		connect(action_geompoint_open, SIGNAL(triggered()), this, SLOT(actionGeomPointOpenSlot())); 
		//RibbonTitle
		connect(m_ribbon_title, &RibbonTitle::actionAppPrinter, this, &RibbonStyle::actionAppPrinter);
		connect(m_ribbon_title, &RibbonTitle::actionAppRedo, this, &RibbonStyle::actionAppRedo);
		connect(m_ribbon_title, &RibbonTitle::actionAppUndo, this, &RibbonStyle::actionAppUndo);

		loadRecentFiles();
		initIndex();
		initPart();
		initProgram();
		initDataBase();


	}

	RibbonStyle::~RibbonStyle() {
		if (!m_main_menu) delete m_main_menu;
		if (!m_recent_open) delete m_recent_open;

	}



	void RibbonStyle::initIndex() {
		RibbonCategory* category_index = addCategory("主页");
		RibbonPannel* pannel_file = category_index->addPannel("文件");
		/*添加主页项*/
		pannel_file->addAction(action_model_new, 2);

		m_new_window = new QAction(QIcon(":/Res/icon_new_renderer.png"), "新建窗口", m_p);
		connect(m_new_window, &QAction::triggered, this, &RibbonStyle::actionNewRenderer);

		RibbonPannel* pannel_renderer = category_index->addPannel("渲染窗口");
		pannel_renderer->addAction(m_new_window, 2);
		//m_process_name = new QLineEdit("0x453DF", m_p);
		//QPalette _palette = m_process_name->palette();
		//_palette.setColor(QPalette::Text, Qt::blue);
		//m_process_name->setPalette(_palette);
		//m_rogress_bar = new QProgressBar(m_p);
		//m_rogress_bar->setTextVisible(false);


		/*添加主页项*/
		RibbonPannel* pannel_soft = addCategory("主页")->addPannel("程序");
		pannel_soft->addAction(action_app_close, 2);
		pannel_soft->addAction(action_app_help, 2);

	}


	void RibbonStyle::initPart() {
		RibbonCategory* category_part = addCategory("几何");
		RibbonPannel* pannel_sketch = category_part->addPannel("草图"); 
		RibbonPannel* pannel_base = category_part->addPannel("基本");
		RibbonPannel* pannel_edit = category_part->addPannel("编辑");
		RibbonPannel* pannel_measure = category_part->addPannel("测量");

		QActionGroup* sketch_group = new QActionGroup(this);
		sketch_group->setEnabled(false);
		m_draw_sketch = new QAction(QIcon(":/Res/icon_geometry_sketch.png"), "草图绘制", this);
		m_draw_sketch->setCheckable(true);
		connect(m_draw_sketch, &QAction::triggered, this, [=] {
			emit actionDrawSketch(m_draw_sketch); 
			sketch_group->setEnabled(m_draw_sketch->isChecked());
		});
		pannel_sketch->addAction(m_draw_sketch, 2);

		QAction* sketch_line = new QAction(QIcon(":/Res/icon_sketch_line.png"), "线段", sketch_group);
		QAction* sketch_rectangle = new QAction(QIcon(":/Res/icon_sketch_rectangle.png"), "矩形", sketch_group);
		QAction* sketch_circle = new QAction(QIcon(":/Res/icon_sketch_circle.png"), "圆形", sketch_group);
		QAction* sketch_arc = new QAction(QIcon(":/Res/icon_sketch_arc.png"), "圆弧", sketch_group);
		QAction* sketch_polyline = new QAction(QIcon(":/Res/icon_sketch_polyline.png"), "多段线", sketch_group);
		QAction* sketch_curve = new QAction(QIcon(":/Res/icon_sketch_curve.png"), "曲线", sketch_group);

		pannel_sketch->addAction(sketch_line, 0);
		pannel_sketch->addAction(sketch_rectangle, 0);
		pannel_sketch->addAction(sketch_circle, 0);
		pannel_sketch->addAction(sketch_arc, 0);
		pannel_sketch->addAction(sketch_polyline, 0);
		pannel_sketch->addAction(sketch_curve, 0);
		 
		m_shape_cylinder = new QAction(QIcon(":/Res/icon_shape_cylinder.png"), "圆柱", this);
		m_shape_pyramid = new QAction(QIcon(":/Res/icon_shape_pyramid.png"), "棱锥", this);
		m_shape_cone = new QAction(QIcon(":/Res/icon_shape_cone.png"), "圆锥", this);
		m_shape_more = new QAction(QIcon(":/Res/icon_shape_cube.png"), "更多", this);
		QMenu* shape_more = new QMenu(m_p); 
		m_shape_more->setMenu(shape_more); 
		m_shape_sphere = new QAction(QIcon(":/Res/icon_shape_sphere.png"), "圆球", this);
		m_shape_cube = new QAction(QIcon(":/Res/icon_shape_cube.png"), "正方", this);
		shape_more->addAction(m_shape_sphere);
		shape_more->addAction(m_shape_cube);

		pannel_base->addAction(m_shape_cylinder, 1);
		pannel_base->addAction(m_shape_pyramid, 1);
		pannel_base->addAction(m_shape_cone, 1);
		pannel_base->addAction(m_shape_more, 2);


		m_point_distance = new QAction(QIcon(":/Res/icon_point_distance.png"), "节点间距", this);
		m_elemt_distance = new QAction(QIcon(":/Res/icon_element_distance.png"), "单元间距", this);
		m_point_distance->setCheckable(true);
		m_elemt_distance->setCheckable(true);
		pannel_measure->addAction(m_point_distance, 1);
		pannel_measure->addAction(m_elemt_distance, 1); 

		connect(m_point_distance, &QAction::triggered, this, [=]() {emit actionDistanceForPoints(m_point_distance); });
		connect(m_elemt_distance, &QAction::triggered, this, [=]() {emit actionDistanceForPoints(m_elemt_distance); }); 

	}


	void RibbonStyle::initProgram() {
		RibbonCategory* category_program = addCategory("程序");
		RibbonPannel* pannel_forming = category_program->addPannel("成形");
		RibbonPannel* pannel_strengthen = category_program->addPannel("强化");

		pannel_forming->addAction(new QAction(QIcon(":/Res/icon_program_LPF.png"), "冲击成形", this), 2);
		pannel_forming->addAction(new QAction(QIcon(":/Res/icon_program_IS.png"), "固有应变法", this), 2);
		pannel_strengthen->addAction(new QAction(QIcon(":/Res/icon_program_LSP.png"), "冲击强化", this), 2);


	}


	void RibbonStyle::initDataBase() {
		RibbonCategory* category_database = addCategory("数据库");
		RibbonPannel* pannel_database = category_database->addPannel("数据库"); 
		RibbonPannel* pannel_data = category_database->addPannel("数据");
		RibbonPannel* pannel_material = category_database->addPannel("材料"); 
		RibbonPannel* pannel_exp = category_database->addPannel("数据分析");

		pannel_database->addAction(new QAction(QIcon(":/Res/icon_database_exp.png"), "试验数据", this), 2);
		pannel_database->addAction(new QAction(QIcon(":/Res/icon_database_simulation.png"), "仿真数据", this), 2);
		pannel_database->addAction(new QAction(QIcon(":/Res/icon_add_database.png"), "连接", this), 1);
		pannel_database->addAction(new QAction(QIcon(":/Res/icon_accept_database.png"), "更新", this), 1);
		pannel_database->addAction(new QAction(QIcon(":/Res/icon_delete_database.png"), "断开", this), 1);

		pannel_data->addAction(new QAction(QIcon(":/Res/icon_data_add.png"), "添加数据", this), 2);


		pannel_material->addAction(new QAction(QIcon(":/Res/icon_material_settings.png"), "管理材料", this), 2);
		pannel_material->addAction(new QAction(QIcon(":/Res/icon_material_add.png"), "添加材料", this), 1);
		pannel_material->addAction(new QAction(QIcon(":/Res/icon_material_remove.png"), "移除材料", this), 1);

	}


	void RibbonStyle::addRecentFile(QString file) {
		QSettings settings(INI_PATH, QSettings::IniFormat);
		settings.setIniCodec("utf-8");
		settings.beginGroup("Files");
		QStringList recent_files = settings.value("RencentFiles", "").toString().split("\n", Qt::SkipEmptyParts);
		if (!recent_files.contains(file)) {
			recent_files << file;
			QAction* recent = new QAction(file, this);
			m_recent_open->addAction(recent);
			connect(recent, &QAction::triggered, this, [=] {emit actionFileOpen(recent->text()); });
		}
		if (recent_files.count() > MAX_FILES) {
			recent_files.removeFirst();
		}
		settings.setValue("RencentFiles", recent_files.join("\n"));
		settings.endGroup();

	}

	void RibbonStyle::loadRecentFiles() {
		QSettings settings(INI_PATH, QSettings::IniFormat);
		settings.setIniCodec("utf-8");
		settings.beginGroup("Files");
		QStringList recent_files = settings.value("RencentFiles", "").toString().split("\n", Qt::SkipEmptyParts);
		for (const auto& recent : recent_files) {
			QAction* file = new QAction(recent, this);
			m_recent_open->addAction(file);
			connect(file, &QAction::triggered, this, [=] {emit actionFileOpen(file->text()); });
		}
		settings.setValue("RencentFiles", recent_files.join("\n"));
		settings.endGroup();

	}


	RibbonCategory* RibbonStyle::addCategory(QString name, QIcon icon) {
		if (m_categories.contains(name)) {
			return dynamic_cast<RibbonCategory*>(m_categories.value(name));
		}
		RibbonCategory* category = new RibbonCategory(m_p);
		m_categories.insert(name, category);
		m_ribbon_tab->addTab(category, icon, name);

		return category;
	}

	void RibbonStyle::actionGeomPointOpenSlot() {
		auto _parent = m_p;
		QString filename = QFileDialog::getOpenFileName(
			_parent, tr("选择一个包含几何点的文件"),
			"./", tr("IGES几何文件(*.iges; *.igs);; "
				"TXT文本文件(*.txt);; "
				"表格文件(*.csv);; "
			));

		if (filename.isEmpty()) {
			return;
		}
		emit actionGeomPointOpen(filename);
	}




	void RibbonStyle::actionSetWorkpathSlot() {
		QString filename = QFileDialog::getExistingDirectory(
			m_p, tr("选择工作路径"),
			"./" );
		if (filename.isEmpty()) {
			return;
		}
		emit actionSetWorkpath(filename);

	}

	void RibbonStyle::actionFileOpenSlot() {
		auto _parent = m_p;
		QString filename = QFileDialog::getOpenFileName(
			_parent, tr("选择一个几何模型文件"),
			"./", tr("Step文件(*.step; *.stp);; "
				"Iges文件(*.iges; *.igs);; "
				"Stl文件(*.stl);; "
				"vtk文件(*.vtk; *.vtu);; "
				"Inp文件(*.inp;);; "
				"Mesh文件(*.msh;)"
			));

		if (filename.isEmpty()) {
			return;
		}
		emit actionFileOpen(filename);
	}



	void RibbonStyle::actionModelNewSlot() {
		bool _ret = false;
		auto _parent = m_p;
		QString text = QInputDialog::getText(_parent, "模型名称", "名称(:英文)", QLineEdit::Normal, "Deafult-Model", &_ret, Qt::MSWindowsFixedSizeDialogHint);
		auto isEnglish = [](const QString& str) {
			for (const QChar& c : str) {
				if (c.unicode() > 127) { 
					return false;
				}
			}
			return true;
		};
		bool is_english = isEnglish(text);
		if (_ret && !text.isEmpty() && is_english) {
			emit actionModelNew(text);
			return;
		}
		else if (!is_english) {
			QMessageBox::warning(_parent, "警告", "模型名称含有非法字符. ");
			return;
		}
		QMessageBox::warning(_parent, "警告", "模型名称不能为空. ");
	}

}
